package com.example.springboot.service.impl;


import com.example.springboot.dao.UserMapper;
import com.example.springboot.utils.JwtUtils;
import com.example.springboot.utils.SqlString;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.example.springboot.domain.*;
import com.example.springboot.service.UserService;
import com.example.springboot.utils.Md5;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @javax.annotation.Resource
    private UserMapper userMapper;

    String key="example.springboot";

    @javax.annotation.Resource
    public AuthenticationManager authenticationManager;

    @javax.annotation.Resource
    RedisTemplate<String,LoginUser> redisTemplate;

    BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
    /*
        用户分页&多条件组合查询
     */
    @Override
    public PageInfo findAllUserByPage(UserVo userVo) {
        userVo.setPhone(SqlString.replaceLike(userVo.getPhone()));
        PageHelper.startPage(userVo.getCurrentPage(),userVo.getPageSize());
        List<User> allUserByPage = userMapper.findAllUserByPage(userVo);

        PageInfo<User> pageInfo = new PageInfo<>(allUserByPage);
        return pageInfo;
    }

    /*
        用户登陆
     */
    @Override
    public ResponseResult login(User user) throws Exception {

        //AuthenticationManager.authenticate进行用户认证
        user.setPassword(Md5.md5(user.getPassword(),Md5.md5key));
      //  System.out.println(bcryptPasswordEncoder.encode(user.getPassword()));
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user.getPhone(), user.getPassword());
        Authentication authentication= authenticationManager.authenticate(authenticationToken);
        //判断认证结果
        if(Objects.isNull(authentication)){
            return  new ResponseResult(true,400,"用户名密码错误",null);
        }

        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String id = String.valueOf(loginUser.getUser().getId());
        String token= JwtUtils.createJwt(id);

        redisTemplate.opsForValue().set("login:"+id, loginUser);
        redisTemplate.expire("login:"+id,600000, TimeUnit.SECONDS);
        Map<String, Object> map = new HashMap<>(3);
            map.put("access_token",token);
            map.put("user_id",loginUser.getUser().getId());
            // 将查询出来的user,也存到map中
            map.put("user",loginUser.getUser());
        return new ResponseResult(true,1,"登陆成功",map);

    }

    @Override
    public boolean register(User user) {
        User user2 = userMapper.login(user);
        if(user2==null) {
            Date date = new Date();
            user.setCreate_time(date);
            user.setUpdate_time(date);
            user.setAccount_non_expired(1);
            user.setCredentials_non_expired(1);
            user.setAccount_non_locked(1);
            user.setIs_del(0);
            user.setStatus("ENABLE");
            String pwd= null;
            try {
                pwd = Md5.md5(user.getPassword(),Md5.md5key);
            } catch (Exception e) {
                e.printStackTrace();
            }
            user.setPassword(bcryptPasswordEncoder.encode(pwd));
            userMapper.register(user);
            return true;
        } else {
            return  false;
        }

    }

    /*
        分配角色（回显）
     */
    @Override
    public List<Role> findUserRelationRoleById(Integer id) {
        List<Role> list = userMapper.findUserRelationRoleById(id);

        return list;
    }


    @Override
    public void userContextRole(UserVo userVo) {

        // 1.根据用户ID清空中间表关联关系
        userMapper.deleteUserContextRole(userVo.getUserId());

        System.out.println(userVo);
        // 2.再从新建立关联关系
        for (Integer roleid : userVo.getRoleIdList()) {

            // 封装数据
            User_Role_relation user_role_relation = new User_Role_relation();
            user_role_relation.setUserId(userVo.getUserId());
            user_role_relation.setRoleId(roleid);

            Date date = new Date();
            user_role_relation.setCreatedTime(date);
            user_role_relation.setUpdatedTime(date);

            user_role_relation.setCreatedBy("system");
            user_role_relation.setUpdatedby("system");
            System.out.println(user_role_relation);
            userMapper.userContextRole(user_role_relation);

        }

    }

    /*
        获取用户权限信息
     */
    @Override
    public ResponseResult getUserPermissions(Integer userid) {

        // 1. 获取当前用户拥有的角色
        List<Role> roleList = userMapper.findUserRelationRoleById(userid);

        // 2. 获取角色ID，保存到List集合中
        ArrayList<Integer> roleIds = new ArrayList<>();

        for (Role role : roleList) {
            roleIds.add(role.getId());
        }

        // 3.根据角色ID查询父菜单
        List<Menu> parentMenu = userMapper.findParentMenuByRoleId(roleIds);

        // 4.查封封装父菜单关联的子菜单
        for (Menu menu : parentMenu) {
            List<Menu> subMenu = userMapper.findSubMenuByPid(menu.getId());
            menu.setSubMenuList(subMenu);
        }

        // 5.获取资源信息
        List<Resource> resourceList = userMapper.findResourceByRoleId(roleIds);


        // 6. 封装数据并返回
        Map<String, Object> map = new HashMap<>();
        map.put("menuList",parentMenu);
        map.put("resourceList",resourceList);



        return new ResponseResult(true,200,"获取用户权限信息成功",map);
    }

    @Override
    public boolean updateUserStatus(Integer userId,String status) {
        int flag=userMapper.updateUserStatus(userId,status);
        if(flag>0){
            return true;
        }
        return false;
    }


}
